package com.karaoke.android.home.vm

import android.databinding.ObservableArrayList
import android.databinding.ObservableBoolean
import android.databinding.ObservableField
import android.databinding.ObservableInt
import android.view.Surface
import android.view.SurfaceHolder
import com.apkfuns.logutils.LogUtils
import com.karaoke.android.data.*
import com.karaoke.android.data.domain.*
import com.karaoke.android.data.krealmextensions.queryAll
import com.karaoke.android.data.krealmextensions.queryFirst
import com.karaoke.android.data.krealmextensions.saveAll
import com.karaoke.android.data.service.MediaListService
import com.karaoke.android.library.mvvm.FragmentViewModel
import com.karaoke.android.player.VideoManager
import com.karaoke.android.player.VideoManagerListener
import org.simple.eventbus.EventBus
import org.simple.eventbus.Subscriber
import rx.Observable
import rx.Subscription
import java.util.concurrent.TimeUnit

/**
 * Created by allen on 17-4-14.
 */

class VideoViewModel : FragmentViewModel(), VideoManagerListener
{
    override fun onToggleService()
    {
        val cmd = if (isService.get()) CLIENT_CLEAN_SERVICE else CLIENT_REQUEST_SERVICE
        Room().queryFirst()?.let {
            NetworkTools.udpClient.sendMessage(UdpMessage(cmd, it.no))
            isService.set(!isService.get())
        }
    }

    override fun onCurrentPositionChanged(position: Int)
    {
        progressValue.set(position)
    }

    override fun onStart(manager: VideoManager)
    {
        currentPlay.set(MediaListService.mediaList.current)
        hideSongName?.unsubscribe()
        currentText.set("当前播放:${currentPlay.get().name}")
        val next = MediaListService.nextSong()
        if (next != null)
        {
            nextText.set("下首播放:${next.name}")
        }
        else
        {
            nextText.set("无点播曲目")
        }
        currentTextVisibility.set(true)
        nextTextVisibility.set(true)
        hideSongName = hideUIFlag("songName")
        NetworkTools.webSocketClient.sendMessage(Message<String>(Command.SongStartPlay).apply { value = currentPlay.get().id })
    }

    override fun onVideoPause(isPause: Boolean)
    {
        this.isPause.set(isPause)
    }

    override fun onAutoCompletion()
    {
        NetworkTools.webSocketClient.sendMessage(Message<String>(Command.SongPlayed).apply { value = currentPlay.get().id })
        MediaListService.nextPlay()
    }

    override fun onError(what: Int, extra: Int)
    {
    }

    override fun onInfo(what: Int, extra: Int)
    {
    }

    override fun onAccompanyChanged(accompany: VideoManager.Accompany)
    {
        this.accompany.set(accompany)
        hideYB?.unsubscribe()
        accompanyFlag.set(true)
        hideYB = hideUIFlag("YB")
    }

    override fun onMute(boolean: Boolean)
    {
        this.isMute.set(boolean)
    }

    fun startPlayCurrent()
    {
        val s = MediaListService.mediaList.current
        if (s == null)
        {
            MediaListService.nextPlay()
        }
        else
        {
            startPlay(s)
        }
    }

    private fun startPlay(song: Song)
    {
        mSurface?.let { VideoManager.startPlayVideo(song, it) }
    }

    private var mSurface: Surface? = null
        set(value)
        {
            field = value
            value?.let {
                startPlayCurrent()
            }
        }
    val surfaceCallBack = object : SurfaceHolder.Callback
    {
        override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int)
        {
            LogUtils.w("surfaceChanged $format $width $height")
        }

        override fun surfaceDestroyed(holder: SurfaceHolder?)
        {
            LogUtils.w("surfaceDestroyed $holder")
        }

        override fun surfaceCreated(holder: SurfaceHolder?)
        {
            LogUtils.w("surfaceCreated $holder")
            mSurface = holder?.surface
        }
    }

    init
    {
        EventBus.getDefault().register(this)
    }

    override fun onStart()
    {
        super.onStart()
    }

    override fun onDestroy()
    {
        EventBus.getDefault().unregister(this)
        super.onDestroy()
    }


    override fun onVolumeChanged(volume: Float)
    {
        volumeFlag.set(true)
        this.volume.set((volume * 100).toInt())
        this.volumePercentage.set("${(volume * 100).toInt()}%")
        hideVolBarSub?.unsubscribe()
        hideVolBarSub = hideUIFlag("vol")
    }

    @Subscriber(tag = "currentChanged")
    fun onCurrentChanged(song: Song)
    {
        currentPlay.set(song)
        startPlay(song)
    }


    private var hideVolBarSub: Subscription? = null
    private var hideSongName: Subscription? = null
    private var hideYB: Subscription? = null

    private fun hideUIFlag(flag: String): Subscription
    {
        return Observable.just(flag).delay(8, TimeUnit.SECONDS).onUI {
            when (flag)
            {
                "vol"      -> volumeFlag.set(false)
                "songName" ->
                {
                    currentTextVisibility.set(false)
                    nextTextVisibility.set(false)
                }
                "YB"       ->
                {
                    accompanyFlag.set(false)
                }
            }
        }
    }


    val volumeFlag = ObservableBoolean()
    val volume = ObservableInt()
    val volumePercentage = ObservableField<String>()
    val currentText = ObservableField<String>().apply { set("") }
    val currentTextVisibility = ObservableBoolean()
    val nextText = ObservableField<String>().apply { set("") }
    val nextTextVisibility = ObservableBoolean()
    val serviceVisibility = ObservableBoolean()
    val currentPlay = ObservableField<Song>()


    val isMute = ObservableBoolean()
    val isService = ObservableBoolean()
    val isPause = ObservableBoolean()
    val accompany = ObservableField<VideoManager.Accompany>()
    val progressValue = ObservableInt()
    val scrollTexts = ObservableArrayList<ScrollText>().apply {
        addAll(ScrollText().queryAll())
    }

    /**
     * 原伴唱标志
     */
    val accompanyFlag = ObservableBoolean()

    override fun onCreate()
    {
        super.onCreate()
        VideoManager.addListener(this)
        if (MediaListService.publicSongs.isEmpty())
        {
            NetworkTools.roomService.getPublicSongs().onIO()
                    .onUI({
                              MediaListService.publicSongs = it
                              if (MediaListService.mediaList.current == null)
                              {
                                  MediaListService.nextPlay()
                              }
                          }, {})
        }

        if (scrollTexts.isEmpty())
        {
            NetworkTools.roomService.getScrollTexts().onIO()
                    .onUI({ it.saveAll();scrollTexts.addAll(it) }, {})
        }

    }

    fun onDismiss()
    {
    }

    @Subscriber(tag = CLIENT_CLEAN_SERVICE)
    fun onCleanService(message: UdpMessage)
    {
        isService.set(false)
    }
}
